Add example for Espressif ESP32 executorch runner with no optimizations#18224
Add example for Espressif ESP32 executorch runner with no optimizations#18224jpiat wants to merge 22 commits intopytorch:mainfrom
Conversation
…e it included in runner
…play correct error messages
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/18224
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 Awaiting Approval, 2 New Failures, 1 Cancelled Job, 1 Unrelated FailureAs of commit d35b30f with merge base d2ce595 ( NEW FAILURES - The following jobs have failed:
CANCELLED JOB - The following job was cancelled. Please retry:
BROKEN TRUNK - The following job failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
Hi @jpiat! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
There was a problem hiding this comment.
Pull request overview
Adds an Espressif (ESP32 / ESP32-S3) ExecuTorch “executor runner” example project plus a new CMake preset to help cross-compile ExecuTorch for ESP targets.
Changes:
- Introduces a new
esp-baremetalCMake preset and preset file for ESP-oriented ExecuTorch builds. - Adds a full ESP-IDF example project (runner component + template project + build script + docs).
- Adds ESP-IDF configuration defaults (sdkconfig defaults + partition table) for ESP32-S3-oriented setups.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New ESP-oriented ExecuTorch build preset settings. |
| CMakePresets.json | Registers the esp-baremetal configure preset. |
| examples/espressif/README.md | End-to-end instructions for exporting, building, flashing, and troubleshooting on ESP32/ESP32-S3. |
| examples/espressif/build.sh | Helper script to build the ESP-IDF project and optionally generate model_pte.h. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component + standalone build definition for the runner. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Main ESP runner implementation (PAL hooks, loading, execution, optional FS load/ETDump/BundleIO). |
| examples/espressif/executor_runner/esp_memory_allocator.{h,cpp} | ESP-specific allocator wrapper with usage tracking. |
| examples/espressif/executor_runner/esp_perf_monitor.{h,cpp} | Simple perf measurements using cycle counter + esp_timer. |
| examples/espressif/executor_runner/pte_to_header.py | Converts .pte into a C header for compiled-in model embedding. |
| examples/espressif/project/CMakeLists.txt | Template ESP-IDF project that pulls in the runner component. |
| examples/espressif/project/main/{CMakeLists.txt,main.cpp} | Minimal “main” component that calls into the runner. |
| examples/espressif/project/sdkconfig.defaults | Default ESP-IDF configuration for the example (generic). |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | Target-specific ESP32-S3 config defaults. |
| examples/espressif/project/partitions.csv | Custom partition table for the example firmware. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
@pytorchbot label "release notes: examples" |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new Espressif ESP32/ESP32-S3 example integration for running ExecuTorch models under ESP-IDF, along with build tooling and documentation to cross-compile ExecuTorch for Xtensa and build/flash an example project.
Changes:
- Introduces an ESP-IDF
executor_runnercomponent and example project scaffolding (CMake,app_main, sdkconfig defaults, partitions). - Adds an ESP-focused CMake preset (
esp-baremetal) to configure ExecuTorch builds for the target. - Adds a model conversion helper (
pte_to_header.py), a build helper script, and a comprehensive README.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New preset to configure ExecuTorch build options for ESP targets. |
| CMakePresets.json | Registers the esp-baremetal CMake preset. |
| examples/espressif/README.md | End-to-end documentation for exporting, building, flashing, and troubleshooting. |
| examples/espressif/build.sh | Helper script to generate model_pte.h and build via idf.py. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component definition + standalone CMake build option; integrates prebuilt ExecuTorch libs. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Core runner implementation: loading PTE, setting up allocators, executing, logging, optional SPIFFS load. |
| examples/espressif/executor_runner/esp_memory_allocator.{h,cpp} | Custom allocator wrapper with tracking helpers. |
| examples/espressif/executor_runner/esp_perf_monitor.{h,cpp} | Perf measurement helpers using cycle counter and esp_timer. |
| examples/espressif/executor_runner/pte_to_header.py | Converts a .pte into a C header byte array for firmware embedding. |
| examples/espressif/project/CMakeLists.txt | Example ESP-IDF project top-level CMake. |
| examples/espressif/project/main/CMakeLists.txt | Minimal main component that depends on executor_runner. |
| examples/espressif/project/main/main.cpp | Provides app_main() that invokes executor_runner_main(). |
| examples/espressif/project/sdkconfig.defaults | Baseline ESP-IDF defaults for the example project. |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3-specific defaults (PSRAM, etc.). |
| examples/espressif/project/partitions.csv | Custom partition table template for the example project. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
…atching result type
There was a problem hiding this comment.
Pull request overview
This pull request adds an Espressif ESP32/ESP32-S3 ExecuTorch “executor runner” example plus a CMake preset to support cross-compiling ExecuTorch for ESP targets.
Changes:
- Introduces a new
esp-baremetalCMake preset and preset file to configure an ESP-oriented ExecuTorch build. - Adds a full ESP-IDF example project + build script + documentation for running
.ptemodels on ESP32/ESP32-S3. - Adds ESP-specific runtime utilities (performance monitor, memory allocator) and an ESP executor runner implementation.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New preset file defining default ExecuTorch build toggles for ESP builds. |
| CMakePresets.json | Adds esp-baremetal configure preset entry. |
| extension/threadpool/threadpool.cpp | Adjusts TSAN thread limit constant type in get_threadpool(). |
| examples/espressif/README.md | New end-to-end documentation for ESP32/ESP32-S3 runner and workflow. |
| examples/espressif/build.sh | New helper script to generate model_pte.h and build the ESP-IDF project. |
| examples/espressif/executor_runner/CMakeLists.txt | Defines ESP-IDF component + standalone build wiring for the runner. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Main ESP runner implementation (PAL hooks, allocators, optional FS load, execution loop). |
| examples/espressif/executor_runner/esp_memory_allocator.h | Declares a tracking allocator wrapper for embedded diagnostics. |
| examples/espressif/executor_runner/esp_memory_allocator.cpp | Implements tracking allocator accounting. |
| examples/espressif/executor_runner/esp_perf_monitor.h | Declares ESP timing/profiling helpers. |
| examples/espressif/executor_runner/esp_perf_monitor.cpp | Implements cycle/time measurement + logging for ESP builds (stubbed for non-ESP). |
| examples/espressif/executor_runner/pte_to_header.py | Utility to convert .pte into a compiled-in C header. |
| examples/espressif/project/CMakeLists.txt | Template ESP-IDF project using the runner component via EXTRA_COMPONENT_DIRS. |
| examples/espressif/project/main/CMakeLists.txt | Minimal main component definition for the ESP-IDF app. |
| examples/espressif/project/main/main.cpp | ESP-IDF app_main() that calls executor_runner_main(). |
| examples/espressif/project/sdkconfig.defaults | Baseline ESP-IDF config defaults for the example. |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3 specific ESP-IDF config defaults (PSRAM/oct mode, etc.). |
| examples/espressif/project/partitions.csv | Custom partition table for the example project. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Adds an Espressif ESP32/ESP32-S3 executor runner example and build scaffolding to cross-compile and run ExecuTorch on ESP-IDF targets, plus a small threadpool type tweak and a new CMake preset for ESP baremetal builds.
Changes:
- Add a full ESP-IDF example project/component for running ExecuTorch models on ESP32/ESP32-S3 (runner, perf monitor, allocator, build script, docs, sdkconfigs, partition table).
- Add an
esp-baremetalCMake preset and corresponding preset file for cross-compiling ExecuTorch for ESP targets. - Adjust threadpool TSAN thread-limit constant type to match the detected thread-count type.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New build preset configuration for ESP baremetal/cross builds. |
| CMakePresets.json | Registers esp-baremetal configure preset. |
| extension/threadpool/threadpool.cpp | Uses decltype(result) for TSAN thread-limit constant type alignment. |
| examples/espressif/README.md | ESP32/ESP32-S3 usage and build instructions. |
| examples/espressif/build.sh | Helper script to generate model header and build via idf.py. |
| examples/espressif/project/CMakeLists.txt | ESP-IDF example project wiring and component path setup. |
| examples/espressif/project/main/CMakeLists.txt | ESP-IDF main component registering main.cpp. |
| examples/espressif/project/main/main.cpp | Example app_main() that calls executor_runner_main(). |
| examples/espressif/project/sdkconfig.defaults | Default ESP-IDF config for the example. |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3-specific defaults (Octal PSRAM, etc.). |
| examples/espressif/project/partitions.csv | Example partition table for the ESP-IDF project. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component definition + linkage to prebuilt ExecuTorch libs; optional ETDump/BundleIO. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Core ESP runner implementation (PAL hooks, memory pools, model loading, execution loop). |
| examples/espressif/executor_runner/esp_perf_monitor.h | Perf monitor API for cycle/time measurement. |
| examples/espressif/executor_runner/esp_perf_monitor.cpp | Perf monitor implementation using ESP-IDF timers/cycle counter. |
| examples/espressif/executor_runner/esp_memory_allocator.h | Instrumented allocator wrapper for tracking used/free bytes. |
| examples/espressif/executor_runner/esp_memory_allocator.cpp | Implementation of tracked allocator. |
| examples/espressif/executor_runner/pte_to_header.py | Utility to convert .pte into a compiled-in C header array. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // Load model from filesystem | ||
| // Use a temporary allocator for the file loading | ||
| EspMemoryAllocator file_allocator( | ||
| method_allocation_pool_size, method_allocation_pool); | ||
| auto [buffer, buffer_size] = | ||
| load_file_from_fs("/spiffs/model.pte", file_allocator); | ||
| if (buffer == nullptr) { | ||
| ET_LOG(Fatal, "Failed to load model from filesystem."); | ||
| return; | ||
| } | ||
| model_pte = buffer; | ||
| model_pte_size = buffer_size; | ||
| pte_size = buffer_size; |
There was a problem hiding this comment.
This is a legitimate issue. In this example, we use the BufferDataLoader to provide the PTE file to the Program::load(). This will leave the PTE file in place, but point at various structures within it. If that memory block is then re-used for method allocator, we can potentially trample the contents of the PTE file and corrupt it. BufferDataLoader is typically used with a static buffer.
On platforms with filesystems, you would typically use FileDataLoader or MmapDataLoader instead, but those do require malloc as well. If malloc is unavailable, then perhaps we could create a static buffer of the model size, read it into there, and then it would be safe to use with BufferDataLoader.
There was a problem hiding this comment.
Pull request overview
Adds a new Espressif ESP32/ESP32-S3 example that demonstrates running an ExecuTorch .pte model on ESP-IDF (without ESP32-specific op optimizations), along with build tooling/presets to cross-compile ExecuTorch for Xtensa.
Changes:
- Introduces an ESP-IDF “executor_runner” component + sample ESP-IDF project to run a model on ESP32/ESP32-S3.
- Adds an
esp-baremetalCMake preset and corresponding preset file for cross-compiling ExecuTorch. - Minor threadpool type tweak (tsan thread limit constant type) and various helper scripts/configs/docs for the example.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New build preset file for ESP cross-compilation defaults. |
| CMakePresets.json | Adds esp-baremetal configure preset pointing at the new preset file. |
| extension/threadpool/threadpool.cpp | Adjusts tsan thread limit constant type to match result. |
| examples/espressif/README.md | New end-to-end documentation for building/flashing the ESP32 runner. |
| examples/espressif/build.sh | Helper script to generate model header and build the ESP-IDF project. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component (and standalone) CMake build for the runner and its options. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Main ESP32 runner implementation (PAL hooks, memory pools, model load, execution, logging). |
| examples/espressif/executor_runner/esp_memory_allocator.h | Declares a small MemoryAllocator wrapper tracking used/free bytes. |
| examples/espressif/executor_runner/esp_memory_allocator.cpp | Implements used/free tracking and reset for the allocator wrapper. |
| examples/espressif/executor_runner/esp_perf_monitor.h | Declares simple measurement start/stop APIs. |
| examples/espressif/executor_runner/esp_perf_monitor.cpp | Implements cycle/wall-time measurement and logging for ESP builds (stubbed otherwise). |
| examples/espressif/executor_runner/pte_to_header.py | Utility to convert .pte to a compiled-in C header array. |
| examples/espressif/project/CMakeLists.txt | Example ESP-IDF project that pulls in the executor_runner component. |
| examples/espressif/project/main/CMakeLists.txt | ESP-IDF main component definition depending on executor_runner. |
| examples/espressif/project/main/main.cpp | ESP-IDF app_main() that calls executor_runner_main(). |
| examples/espressif/project/sdkconfig.defaults | Default ESP-IDF config for the example (PSRAM, perf opts, logging, etc.). |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3 specific defaults (octal PSRAM, etc.). |
| examples/espressif/project/partitions.csv | Example partition table for the sample project. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| idf_component_register( | ||
| SRCS | ||
| "esp_executor_runner.cpp" | ||
| "esp_memory_allocator.cpp" | ||
| "esp_perf_monitor.cpp" | ||
| INCLUDE_DIRS | ||
| "." | ||
| REQUIRES | ||
| esp_timer | ||
| esp_system | ||
| spiffs | ||
| ) |
rascani
left a comment
There was a problem hiding this comment.
Thanks for this PR @jpiat, this is awesome! My one concern would be testing, as we lack any way to validate that this continues to work.
For ARM, we can use the Corstone FVP simulator to test in CI without hardware. Is there an ESP32 simulator we can use? I know the Xtensa toolchain provide an ISS (xt-run), but I'm not sure about whether we can use that for an ESP32.
| // Load model from filesystem | ||
| // Use a temporary allocator for the file loading | ||
| EspMemoryAllocator file_allocator( | ||
| method_allocation_pool_size, method_allocation_pool); | ||
| auto [buffer, buffer_size] = | ||
| load_file_from_fs("/spiffs/model.pte", file_allocator); | ||
| if (buffer == nullptr) { | ||
| ET_LOG(Fatal, "Failed to load model from filesystem."); | ||
| return; | ||
| } | ||
| model_pte = buffer; | ||
| model_pte_size = buffer_size; | ||
| pte_size = buffer_size; |
There was a problem hiding this comment.
This is a legitimate issue. In this example, we use the BufferDataLoader to provide the PTE file to the Program::load(). This will leave the PTE file in place, but point at various structures within it. If that memory block is then re-used for method allocator, we can potentially trample the contents of the PTE file and corrupt it. BufferDataLoader is typically used with a static buffer.
On platforms with filesystems, you would typically use FileDataLoader or MmapDataLoader instead, but those do require malloc as well. If malloc is unavailable, then perhaps we could create a static buffer of the model size, read it into there, and then it would be safe to use with BufferDataLoader.
I'm not aware of an ESP32 simulator that could be used in CI. Do you know how the raspberry-pi/pico2 example is tested ? |
The pico2 example was done with real hardware. I don't think lack of CI will be a blocker for merging, but was hopeful there might be something for ESP32. It might be good to put a warning in the README that it is not tested with CI and maybe subject to breakages. cc @psiddh |
Added the warning in 86e1db7 |
There was a problem hiding this comment.
Pull request overview
This PR adds a new ESP32/ESP32-S3 example demonstrating how to cross-compile ExecuTorch and run a .pte program via an ESP-IDF-based executor runner (without ESP-specific operator optimizations), plus a CMake preset to configure an ESP “baremetal” build of ExecuTorch.
Changes:
- Add
examples/espressif/with an ESP-IDF project, executor runner component, model-to-header conversion script, and documentation. - Add an
esp-baremetalCMake preset and preset file for configuring ExecuTorch builds for ESP targets. - Minor threadpool type tweak in
extension/threadpool/threadpool.cpp.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New build preset file configuring ExecuTorch options for ESP builds. |
| extension/threadpool/threadpool.cpp | Adjusts TSAN thread limit type to match inferred thread-count type. |
| examples/espressif/README.md | New end-to-end documentation for building/flashing/running the ESP example. |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3-specific ESP-IDF defaults (PSRAM, clocks, partitions, etc.). |
| examples/espressif/project/sdkconfig.defaults | Base ESP-IDF defaults for the example project. |
| examples/espressif/project/partitions.csv | Example partition table used by the ESP-IDF project. |
| examples/espressif/project/main/main.cpp | ESP-IDF app_main() that invokes the executor runner and restarts. |
| examples/espressif/project/main/CMakeLists.txt | Registers the ESP-IDF main component and depends on executor_runner. |
| examples/espressif/project/CMakeLists.txt | ESP-IDF project setup and inclusion of the executor runner component. |
| examples/espressif/executor_runner/pte_to_header.py | Utility script to embed a .pte as a C header. |
| examples/espressif/executor_runner/esp_perf_monitor.h | Perf monitor API for ESP timing/cycle reporting. |
| examples/espressif/executor_runner/esp_perf_monitor.cpp | ESP implementation of perf monitoring + non-ESP stubs. |
| examples/espressif/executor_runner/esp_pal.cpp | ESP PAL overrides (init/abort/ticks/logging/alloc hooks). |
| examples/espressif/executor_runner/esp_memory_allocator.h | Custom allocator wrapper with usage/free accounting. |
| examples/espressif/executor_runner/esp_memory_allocator.cpp | Implementation of the custom allocator wrapper. |
| examples/espressif/executor_runner/esp_executor_runner.h | Public C API for initializing/running the runner and I/O access. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Main ESP executor runner implementation + filesystem loading option. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component + standalone build logic, linking to ExecuTorch libs. |
| examples/espressif/build.sh | Helper script to generate model header and build the ESP-IDF project. |
| CMakePresets.json | Adds the esp-baremetal preset entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| return {1000000, cpu_freq_hz}; | ||
| } | ||
| #endif | ||
| return {1000, 240}; // Default to 240 MHz if we can't get the actual frequency |
| ET_UNUSED et_timestamp_t timestamp, | ||
| et_pal_log_level_t level, | ||
| const char* filename, | ||
| ET_UNUSED const char* function, |
| #include <memory> | ||
| #include <type_traits> | ||
| #include <utility> | ||
| #include <vector> |
| EspMemoryAllocator file_allocator( | ||
| method_allocation_pool_size, method_allocation_pool); | ||
| auto [buffer, buffer_size] = | ||
| load_file_from_fs("/spiffs/model.pte", file_allocator); | ||
| if (buffer == nullptr) { | ||
| ET_LOG(Fatal, "Failed to load model from filesystem."); | ||
| return false; | ||
| } | ||
| model_pte = buffer; | ||
| model_pte_size = buffer_size; | ||
| pte_size = buffer_size; | ||
| #else | ||
| pte_size = sizeof(model_pte); | ||
| #endif | ||
|
|
||
| runner_init(g_runner_ctx, pte_size); |
| static_cast<unsigned long>(tensor_bytes)); | ||
| return false; | ||
| } | ||
|
|
| with open(args.pte, "rb") as fr, open(outfile, "w") as fw: | ||
| data = fr.read() | ||
| hexstream = binascii.hexlify(data).decode("utf-8") | ||
|
|
||
| fw.write( | ||
| "/* Auto-generated model header for ESP32 ExecuTorch runner. */\n" | ||
| ) | ||
| fw.write(f"/* Source: {os.path.basename(args.pte)} ({len(data)} bytes) */\n\n") | ||
| fw.write("#pragma once\n\n") | ||
| fw.write(attr + "model_pte[] = {") | ||
|
|
||
| for i in range(0, len(hexstream), 2): | ||
| if 0 == (i % hex_digits_per_line): | ||
| fw.write("\n") | ||
| fw.write("0x" + hexstream[i : i + 2] + ", ") | ||
|
|
||
| fw.write("\n};\n") | ||
| print( | ||
| f"Input: {args.pte} with {len(data)} bytes. " | ||
| f"Output: {outfile} with {os.path.getsize(outfile)} bytes." | ||
| ) |
There was a problem hiding this comment.
Pull request overview
Adds a new Espressif ESP32/ESP32-S3 example that demonstrates running an ExecuTorch .pte on ESP-IDF (no ESP32-optimized ops), plus a CMake preset to cross-compile ExecuTorch for the target.
Changes:
- Introduces an ESP-IDF-based executor runner component + template project (runner API, PAL, perf monitor, memory allocator, build glue).
- Adds an Espressif example README and helper script for building/flashing and converting
.pte→model_pte.h. - Adds a new
esp-baremetalCMake preset and a small threadpool type fix.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/cmake/preset/esp_baremetal.cmake | New preset defaults for building ExecuTorch for ESP cross-compilation. |
| CMakePresets.json | Registers the new esp-baremetal preset. |
| extension/threadpool/threadpool.cpp | Adjusts tsan thread limit type to match result type. |
| examples/espressif/README.md | End-to-end documentation for exporting, building, flashing, and troubleshooting. |
| examples/espressif/build.sh | Helper script to generate model header and build the ESP-IDF project. |
| examples/espressif/project/CMakeLists.txt | ESP-IDF project wrapper that pulls in the runner component. |
| examples/espressif/project/main/CMakeLists.txt | Minimal main component depending on the runner. |
| examples/espressif/project/main/main.cpp | ESP-IDF app_main() entrypoint that invokes the runner. |
| examples/espressif/project/sdkconfig.defaults | Baseline ESP-IDF defaults (ESP32/ESP32-S3). |
| examples/espressif/project/sdkconfig.defaults.esp32s3 | ESP32-S3-specific sdkconfig defaults (Octal PSRAM, etc.). |
| examples/espressif/project/partitions.csv | Example partition table for the template project. |
| examples/espressif/executor_runner/CMakeLists.txt | ESP-IDF component definition + integration with prebuilt ExecuTorch libs + optional .pte header generation. |
| examples/espressif/executor_runner/esp_executor_runner.h | Public C API for initializing, setting inputs, executing, and reading outputs. |
| examples/espressif/executor_runner/esp_executor_runner.cpp | Core runner implementation: loading PTE, allocators, inputs/outputs, optional BundleIO/ETDump, optional filesystem load. |
| examples/espressif/executor_runner/esp_pal.cpp | ESP PAL overrides (ticks, log emission, init/abort). |
| examples/espressif/executor_runner/esp_memory_allocator.h | Wrapper allocator tracking used/free bytes for instrumentation. |
| examples/espressif/executor_runner/esp_memory_allocator.cpp | Implementation of the tracking allocator. |
| examples/espressif/executor_runner/esp_perf_monitor.h | Perf monitor API for ESP. |
| examples/espressif/executor_runner/esp_perf_monitor.cpp | Cycle/time based measurement and reporting for ESP. |
| examples/espressif/executor_runner/pte_to_header.py | Utility to embed .pte into firmware as a C byte array header. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!ctx.method->ok()) { | ||
| ET_LOG( | ||
| Info, | ||
| "Loading of method %s failed with status 0x%" PRIx32, | ||
| ctx.method_name, | ||
| static_cast<unsigned long>(ctx.method->error())); | ||
| } |
There was a problem hiding this comment.
runner_init() logs when program.load_method() fails but then continues and dereferences *ctx.method.value() (e.g., in input preparation). If the Result is not ok, this can trigger an assert/abort or undefined behavior. Return early (or ET_CHECK_MSG(ctx.method->ok(), ...)) before using the Method when load fails.
| if (!ctx.method->ok()) { | |
| ET_LOG( | |
| Info, | |
| "Loading of method %s failed with status 0x%" PRIx32, | |
| ctx.method_name, | |
| static_cast<unsigned long>(ctx.method->error())); | |
| } | |
| ET_CHECK_MSG( | |
| ctx.method->ok(), | |
| "Loading of method %s failed with status 0x%" PRIx32, | |
| ctx.method_name, | |
| static_cast<unsigned long>(ctx.method->error())); |
| ET_LOG(Fatal, "Failed to load model from filesystem."); | ||
| return false; | ||
| } | ||
| model_pte = buffer; |
There was a problem hiding this comment.
When FILESYSTEM_LOAD is enabled, the model bytes are allocated from method_allocation_pool via file_allocator, but the same method_allocation_pool is then reused for ctx.method_allocator allocations in runner_init(). This can overwrite the PTE buffer that BufferDataLoader/Program still references and corrupt execution. Load the PTE into separate storage (heap/PSRAM), or reserve an initial region in the pool and start the method allocator after it, or switch to a file-backed DataLoader.
| model_pte = buffer; | |
| // Copy the loaded PTE into separate heap/PSRAM storage to avoid it being | |
| // overwritten when method_allocation_pool is reused by runner_init(). | |
| void* heap_pte = std::malloc(buffer_size); | |
| if (heap_pte == nullptr) { | |
| ET_LOG(Fatal, "Failed to allocate heap memory for model PTE."); | |
| return false; | |
| } | |
| std::memcpy(heap_pte, buffer, buffer_size); | |
| model_pte = static_cast<uint8_t*>(heap_pte); |
| static_cast<unsigned long>(buffer_bytes), | ||
| static_cast<unsigned long>(tensor_bytes)); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
et_runner_get_output() validates buffer_bytes but never checks that buffer is non-null before calling memcpy(). If callers pass buffer=nullptr with a non-zero size, this will crash. Add an explicit null check (e.g., require non-null when tensor_bytes > 0).
| } | |
| } | |
| if (tensor_bytes > 0 && buffer == nullptr) { | |
| ET_LOG( | |
| Error, | |
| "Output %lu: null buffer passed for non-empty tensor (size=%lu bytes).", | |
| static_cast<unsigned long>(output_idx), | |
| static_cast<unsigned long>(tensor_bytes)); | |
| return false; | |
| } |
| | Chip | CPU | Internal SRAM | PSRAM (optional) | | ||
| |----------|---------------|---------------|------------------| | ||
| | ESP32 | Xtensa LX6 (dual-core, 240MHz) | ~520KB | 4-8MB | | ||
| | ESP32-S3 | Xtensa LX7 (dual-core, 240MHz) | ~512KB | 2-32MB (Octal) | | ||
|
|
There was a problem hiding this comment.
The markdown table under “Supported Targets” has an extra leading | on each row (|| ...), which renders as an empty first column in GitHub markdown. Use standard table syntax with a single leading pipe per row.
| # Name, Type, SubType, Offset, Size, Flags | ||
| nvs,data,nvs,0x9000,24K, | ||
| phy_init,data,phy,0xf000,4K, | ||
| factory,app,factory,0x10000,2M, |
There was a problem hiding this comment.
The example code enables SPIFFS-based model loading (partition label storage), and the README suggests adding a SPIFFS partition, but the provided partitions.csv doesn’t include a storage,data,spiffs,... entry. Consider adding a commented-out SPIFFS row (or include it by default) so users enabling FILESYSTEM_LOAD don’t hit SPIFFS partition not found.
| factory,app,factory,0x10000,2M, | |
| factory,app,factory,0x10000,2M, | |
| # Optional SPIFFS partition for FILESYSTEM_LOAD (label must be "storage") | |
| # storage,data,spiffs,,1M, |
| set_overridable_option(EXECUTORCH_BUILD_KERNELS_QUANTIZED ON) | ||
| set_overridable_option(EXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL ON) | ||
| set_overridable_option(EXECUTORCH_ENABLE_LOGGING ON) | ||
| set_overridable_option(EXECUTORCH_BUILD_ARM_ETDUMP OFF) |
There was a problem hiding this comment.
This preset uses set_overridable_option(EXECUTORCH_BUILD_ARM_ETDUMP OFF), which stores the value as a CACHE STRING with no description. In tools/cmake/preset/arm_baremetal.cmake, the same knob is defined via define_overridable_option(... BOOL ...), which gives it the right type and makes it discoverable. Consider switching to define_overridable_option here as well (or use a non-Arm-specific option name).
| set_overridable_option(EXECUTORCH_BUILD_ARM_ETDUMP OFF) | |
| define_overridable_option( | |
| EXECUTORCH_BUILD_ARM_ETDUMP | |
| OFF | |
| BOOL | |
| "Enable ETDump devtools support for bare-metal targets" | |
| ) |
Summary
This PR introduce a new example for the ESP32 Espressif SoC. The example implement an executorch runner for the ESP32 platform and a project that executes a simple network. The example does not use ops optimized for ESP32 platform but demonstrate feasibility.
Test plan
This example was tested on a ESP32-S3 development platform. The project compiles and when loaded on the platform show the expected log trace.
cc @psiddh @AdrianLundell @digantdesai